package com.solt.prism.core;

import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.NoSuchElementException;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import net.xeoh.plugins.base.annotations.PluginImplementation;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import com.solt.prism.core.conf.news.Field;
import com.solt.prism.core.conf.news.NewsConf;
import com.solt.prism.core.entity.News;
import com.solt.prism.core.utils.NewsPersistencer;
import com.solt.prism.core.wrapper.WrapperFactory;
import com.solt.prism.plugins.NewsWrapper;
import com.solt.prism.plugins.PluginException;

@PluginImplementation
public class ListSiteCrawler extends AbstractCrawler {
	protected XPath xpath = XPathFactory.newInstance().newXPath();
	protected Integer currCat;
	protected int index = -1;
	protected NodeList currentList;
	private String itemXpath;
	private List<Field> fields;
	private NewsWrapper listWrapper;
	private boolean flag;
	
	@Override
	public void init(NewsConf newsConf, NewsWrapper detailWrapper,
			NewsPersistencer persistencer) throws PluginException {
		super.init(newsConf, detailWrapper, persistencer);
		itemXpath = newsConf.getNewsfields().getListSite().getItemXpath();
		fields = newsConf.getNewsfields().getListSite().getField();
		listWrapper = WrapperFactory.createNewsWrapper(conf, fields);
		flag = newsConf.getNewsfields().getDetailSite().getField().isEmpty();
	}
	
	@Override
	protected boolean makeNewsTask(News news,
			Iterator<Entry<URL, Integer>> urlCatsIter)
			throws NoSuchElementException {
		if (currentList == null || index == -1) {
			Entry<URL, Integer> urlEntry = urlCatsIter.next();
			currCat = urlEntry.getValue();
			currentList = retrieveItemList(urlEntry.getKey());
			if (currentList == null || currentList.getLength() == 0) {
				return false;
			}
			index = currentList.getLength() - 1;
		}
		boolean result = listWrapper.extract(currentList.item(index), news);
		news.setCatId(currCat);
		--index;
		return result && flag;
	}

	private NodeList retrieveItemList(URL url) {
		Document html = pageFetcher.retrieve(url);
		if (html != null) {
			try {
				return (NodeList) xpath.evaluate(itemXpath, html,
						XPathConstants.NODESET);
			} catch (XPathExpressionException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

}
